//
//  UIImage+ExColor.m
//  OC-Example
//
//  Created by lcj on 2020/11/3.
//  Copyright © 2020 apang.men. All rights reserved.
//

#import "UIImage+ExColor.h"

@implementation UIImage (ExColor)

+ (UIImage *)apm_imageWithColor:(UIColor *)color {
    return [UIImage apm_imageWithColor:color  size:CGSizeZero];
}

+ (UIImage *)apm_imageWithColor:(UIColor *)color size:(CGSize)size {
    CGRect rect = CGRectZero;
    if (CGSizeEqualToSize(size, CGSizeZero)) {
        rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    }else {
        rect.size = size;
    }
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return theImage;
}

+ (UIImage *)apm_imageWithColor:(UIColor *)color size:(CGSize)size radius:(CGFloat)radius {
    CGRect rect = CGRectZero;
    if (CGSizeEqualToSize(size, CGSizeZero)) {
        rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    }else {
        rect.size = size;
    }
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    if (radius >0 && radius <= size.width/2.0 && radius <= size.height/2.0 ) {
        UIBezierPath *clipPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
        [color setFill];
        [clipPath fill];
        [clipPath addClip];
    } else {
        CGContextSetFillColorWithColor(context, [color CGColor]);
        CGContextFillRect(context, rect);
    }
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return theImage;
}

+ (UIImage *)apm_gradientImageWithColors:(NSArray<UIColor *> *)colors gradientType:(APMGradientImageType)gradientType size:(CGSize)size radius:(CGFloat)radius {
    if (colors.count < 2) return nil;
    if (CGSizeEqualToSize(size, CGSizeZero)) return nil;
    NSMutableArray * _colors = [NSMutableArray array];
    for (UIColor * _color in colors) {
        [_colors addObject:(__bridge id)_color.CGColor];
    }
    UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);
    CGFloat locations[colors.count];
    float step = 1.0 / (colors.count - 1.0);
    for (NSInteger i = 0; i<colors.count; i++) {
        locations[i] = step * i;
    }
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)_colors, locations);
    CGPoint start;
    CGPoint end;
    switch (gradientType) {
        case APMGradientImageTypeLeftToRight:
            start = CGPointMake(0, 0.5);
            end = CGPointMake(size.width, 0.5);
            break;
        case APMGradientImageTypeTopToBottom:
            start = CGPointMake(0.5, 0);
            end = CGPointMake(0.5, size.height);
            break;
        case APMGradientImageTypeLeftTopToRightBottom:
            start = CGPointMake(0, 0);
            end = CGPointMake(size.width, size.height);
            break;
        case APMGradientImageTypeRightTopToLeftBottom:
            start = CGPointMake(size.width, 0);
            end = CGPointMake(0, size.height);
            break;
        default:
            start = CGPointMake(0, 0.5);
            end = CGPointMake(size.width, 0.5);
            break;
    }
    CGRect rect = {{0,0},size};
    if (radius > 0) {
        UIBezierPath * backPath = [UIBezierPath bezierPathWithRect:rect];
        [[UIColor clearColor] setFill];
        [backPath fill];
        UIBezierPath * radiusPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
        [radiusPath addClip];
    }
    CGContextDrawLinearGradient(context, gradient, start, end, 0);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    CGGradientRelease(gradient);
    CGContextRestoreGState(context);
    CGColorSpaceRelease(colorSpace);
    UIGraphicsEndImageContext();
    return image;
}

+ (UIImage *)apm_gradientImageWithColors:(NSArray<UIColor *> *)colors gradientType:(APMGradientImageType)gradientType size:(CGSize)size {
    return [self apm_gradientImageWithColors:colors gradientType:gradientType size:size radius:0];
}

+ (UIImage *)apm_imageWithSize:(CGSize)size fillColor:(UIColor *)fillColor strokeColor:(UIColor *)strokeColor strokeWidth:(CGFloat)strokeWidth radius:(BOOL)radius {
    if (CGSizeEqualToSize(size, CGSizeZero)) return nil;
    if (strokeColor) {
        strokeWidth = strokeWidth > 0 ? strokeWidth : 1.0;
    }
    UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGRect rect = {{0,0},size};
    if (strokeColor && strokeWidth > 0) {
        if (radius) {
            UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:size.height/2.0];
            [strokeColor setFill];
            [path fill];
            [path addClip];
            CGContextSaveGState(context);
            CGRect _rect = {{strokeWidth,strokeWidth},{size.width - (strokeWidth * 2.0), size.height - (strokeWidth * 2.0)}};
            UIBezierPath *clipPath = [UIBezierPath bezierPathWithRoundedRect:_rect cornerRadius:(size.height-(strokeWidth *2.0))/2.0];
            [fillColor setFill];
            [clipPath fill];
            [clipPath addClip];
        } else {
            UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
            [strokeColor setFill];
            [path fill];
            CGContextSaveGState(context);
            CGRect _rect = {{strokeWidth,strokeWidth},{size.width - (strokeWidth * 2.0), size.height - (strokeWidth * 2.0)}};
            UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:_rect];
            [fillColor setFill];
            [clipPath fill];
            [clipPath addClip];
        }
    } else {
        if (radius) {
            UIBezierPath * radiusPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:size.height/2.0];
            [radiusPath addClip];
        }
        [fillColor setFill];
        UIRectFill(rect);
    }
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

+ (UIImage *)apm_hollowImageWithSize:(CGSize)size lineColor:(UIColor *)lineColor lineWidth:(CGFloat)lineWidth radius:(BOOL)radius {
    if (CGSizeEqualToSize(size, CGSizeZero)) return nil;
    lineColor = lineColor != nil ? lineColor : [UIColor lightGrayColor];
    lineWidth = lineWidth > 0 ? lineWidth : 1.0;
    UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale);
    CGRect rect = {{0,0},size};
    if (radius == YES) {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:size.height/2.0];
        CGRect _rect = {{lineWidth,lineWidth},{size.width - (lineWidth * 2.0), size.height - (lineWidth * 2.0)}};
        UIBezierPath *clipPath = [UIBezierPath bezierPathWithRoundedRect:_rect cornerRadius:(size.height-(lineWidth *2.0))/2.0];
        [path appendPath:[clipPath bezierPathByReversingPath]];
        [lineColor setFill];
        [path fill];
        [path addClip];
    } else {
        UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
        CGRect _rect = {{lineWidth,lineWidth},{size.width - (lineWidth * 2.0), size.height - (lineWidth * 2.0)}};
        UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:_rect];
        [path appendPath:[clipPath bezierPathByReversingPath]];
        [lineColor setFill];
        [path fill];
        [path addClip];
    }
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}
@end
